from typing import Optional, Union, List, Dict, Tuple

from beanie import PydanticObjectId
from fastapi import APIRouter, status
from fastapi.responses import PlainTextResponse

from auth.permission.model import Permission

router = APIRouter()


@router.post("/add", response_model=Permission)
async def add(obj: Permission):
    doc = await obj.insert()
    return doc


@router.delete("/{_id}", response_model=Permission)
async def delete(_id: PydanticObjectId):
    doc = await Permission.get(_id)
    if doc:
        await doc.delete()
        return doc
    return PlainTextResponse(status_code=status.HTTP_404_NOT_FOUND, content='Not Found')


@router.put("/{_id}", response_model=Permission)
async def update(_id: PydanticObjectId, obj: Permission):
    update_query = {"$set": {k: v for k, v in obj.dict().items() if v is not None}}
    doc = await Permission.get(_id)
    if doc:
        await doc.update(update_query)
        return doc
    return PlainTextResponse(status_code=status.HTTP_404_NOT_FOUND, content='Not Found')


@router.get("/{_id}", response_model=Permission)
async def get_one(_id: PydanticObjectId):
    doc = await Permission.get(_id)
    if doc:
        return doc
    return PlainTextResponse(status_code=status.HTTP_404_NOT_FOUND, content='Not Found')


@router.get("/", response_model=List[Permission])
async def get_all():
    data = await Permission.all().to_list()
    return data


@router.post("/list", response_model=Dict[str, Union[int, List[Permission]]])
async def get_list(
        args: Optional[dict] = {},
        page: int = 1, limit: int = 1000,
        sort: Optional[List[Tuple[str, int]]] = [('_id', -1)]):
    count = await Permission.find(args).count()
    data = await Permission.find(args, skip=(page-1)*limit, limit=limit, sort=sort).to_list()
    return {
        "count": count,
        "data": data
    }
